package com.ruoyi.pos.domain.transaction;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * POS销售明细实体类
 * 
 * 用于记录POS销售中的商品明细信息，包括商品基本信息、价格、数量、折扣等
 * 支持普通商品、称重商品、赠品等多种商品类型
 * 
 * @author POS System
 * @since 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class PosSaleDetail extends BaseEntity {
    
    private static final long serialVersionUID = 1L;

    /**
     * 明细ID（主键）
     */
    private Long detailId;

    /**
     * 销售ID
     * 
     * 关联pos_sale表
     */
    @Excel(name = "销售ID")
    @NotNull(message = "销售ID不能为空")
    private Long transactionId;

    /**
     * 销售流水号
     */
    @Excel(name = "销售流水号")
    @NotBlank(message = "销售流水号不能为空")
    @Size(max = 32, message = "销售流水号长度不能超过32个字符")
    private String transactionNo;

    /**
     * 行号
     * 
     * 同一销售中的商品行号，从1开始
     */
    @Excel(name = "行号")
    @NotNull(message = "行号不能为空")
    @Min(value = 1, message = "行号不能小于1")
    private Integer lineNo;

    /**
     * 商品编码
     * 
     * 关联第三方商品系统
     */
    @Excel(name = "商品编码")
    @NotBlank(message = "商品编码不能为空")
    @Size(max = 50, message = "商品编码长度不能超过50个字符")
    private String goodsCode;

    /**
     * 商品名称
     */
    @Excel(name = "商品名称")
    @NotBlank(message = "商品名称不能为空")
    @Size(max = 200, message = "商品名称长度不能超过200个字符")
    private String goodsName;

    /**
     * 商品简称
     */
    @Excel(name = "商品简称")
    @Size(max = 100, message = "商品简称长度不能超过100个字符")
    private String goodsShortName;

    /**
     * 商品条码
     */
    @Excel(name = "商品条码")
    @Size(max = 50, message = "商品条码长度不能超过50个字符")
    private String barcode;

    /**
     * 分类编码
     */
    @Excel(name = "分类编码")
    @Size(max = 50, message = "分类编码长度不能超过50个字符")
    private String categoryCode;

    /**
     * 分类名称
     */
    @Excel(name = "分类名称")
    @Size(max = 100, message = "分类名称长度不能超过100个字符")
    private String categoryName;

    /**
     * 品牌编码
     */
    @Excel(name = "品牌编码")
    @Size(max = 50, message = "品牌编码长度不能超过50个字符")
    private String brandCode;

    /**
     * 品牌名称
     */
    @Excel(name = "品牌名称")
    @Size(max = 100, message = "品牌名称长度不能超过100个字符")
    private String brandName;

    /**
     * 单位
     */
    @Excel(name = "单位")
    @Size(max = 20, message = "单位长度不能超过20个字符")
    private String unit;

    /**
     * 规格
     */
    @Excel(name = "规格")
    @Size(max = 100, message = "规格长度不能超过100个字符")
    private String spec;

    /**
     * 单价
     */
    @Excel(name = "单价")
    @NotNull(message = "单价不能为空")
    @DecimalMin(value = "0.00", message = "单价不能小于0")
    private BigDecimal unitPrice;

    /**
     * 会员价
     */
    @Excel(name = "会员价")
    @DecimalMin(value = "0.00", message = "会员价不能小于0")
    private BigDecimal memberPrice;

    /**
     * 数量
     */
    @Excel(name = "数量")
    @NotNull(message = "数量不能为空")
    @DecimalMin(value = "0.000", message = "数量不能小于0")
    private BigDecimal quantity;

    /**
     * 折扣率(%)
     */
    @Excel(name = "折扣率(%)")
    @DecimalMin(value = "0.00", message = "折扣率不能小于0")
    @DecimalMax(value = "100.00", message = "折扣率不能大于100")
    private BigDecimal discountRate;

    /**
     * 折扣金额
     */
    @Excel(name = "折扣金额")
    @DecimalMin(value = "0.00", message = "折扣金额不能小于0")
    private BigDecimal discountAmount;

    /**
     * 金额
     */
    @Excel(name = "金额")
    @NotNull(message = "金额不能为空")
    @DecimalMin(value = "0.00", message = "金额不能小于0")
    private BigDecimal amount;

    /**
     * 原金额
     * 
     * 折扣前的原始金额
     */
    @Excel(name = "原金额")
    @DecimalMin(value = "0.00", message = "原金额不能小于0")
    private BigDecimal originalAmount;

    /**
     * 积分
     * 
     * 该商品获得的积分
     */
    @Excel(name = "积分")
    @Min(value = 0, message = "积分不能小于0")
    private Integer points;

    /**
     * 是否赠品
     * 
     * 0-否 1-是
     */
    @Excel(name = "是否赠品", readConverterExp = "0=否,1=是")
    @Size(max = 1, message = "是否赠品长度不能超过1个字符")
    private String isGift;

    /**
     * 赠送原因
     */
    @Excel(name = "赠送原因")
    @Size(max = 100, message = "赠送原因长度不能超过100个字符")
    private String giftReason;

    /**
     * 操作员ID
     */
    @Excel(name = "操作员ID")
    private Long operatorId;

    /**
     * 操作员姓名
     */
    @Excel(name = "操作员姓名")
    @Size(max = 50, message = "操作员姓名长度不能超过50个字符")
    private String operatorName;

    /**
     * 备注
     */
    @Excel(name = "备注")
    @Size(max = 200, message = "备注长度不能超过200个字符")
    private String remark;

    /**
     * 创建时间
     */
    @Excel(name = "创建时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    // ==================== 扩展字段 ====================

    /**
     * 商品图片URL（非数据库字段）
     */
    @Excel(name = "商品图片")
    private String imageUrl;

    /**
     * 商品库存（非数据库字段）
     */
    @Excel(name = "商品库存")
    private BigDecimal stockQuantity;

    /**
     * 是否赠品显示名称（非数据库字段）
     */
    @Excel(name = "赠品状态")
    private String giftDisplay;

    /**
     * 实际单价（非数据库字段）
     * 
     * 考虑会员价后的实际单价
     */
    @Excel(name = "实际单价")
    private BigDecimal actualPrice;

    // ==================== 业务方法 ====================

    /**
     * 获取是否赠品显示名称
     */
    public String getGiftDisplay() {
        if (isGift == null) {
            return "否";
        }
        return "1".equals(isGift) ? "是" : "否";
    }

    /**
     * 判断是否为赠品
     */
    public boolean isGift() {
        return "1".equals(isGift);
    }

    /**
     * 获取实际单价
     * 
     * 优先使用会员价，其次使用普通单价
     */
    public BigDecimal getActualPrice() {
        if (memberPrice != null && memberPrice.compareTo(BigDecimal.ZERO) > 0) {
            return memberPrice;
        }
        return unitPrice != null ? unitPrice : BigDecimal.ZERO;
    }

    /**
     * 计算折扣金额
     * 
     * @return 折扣金额
     */
    public BigDecimal calculateDiscountAmount() {
        if (originalAmount == null || discountRate == null) {
            return BigDecimal.ZERO;
        }
        
        if (discountRate.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        return originalAmount.multiply(discountRate.divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP))
                            .setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算实际金额
     * 
     * @return 实际金额 = 原金额 - 折扣金额
     */
    public BigDecimal getActualAmount() {
        BigDecimal original = originalAmount != null ? originalAmount : BigDecimal.ZERO;
        BigDecimal discount = discountAmount != null ? discountAmount : BigDecimal.ZERO;
        return original.subtract(discount);
    }

    /**
     * 获取商品完整信息
     * 
     * @return 商品完整信息
     */
    public String getGoodsFullInfo() {
        StringBuilder info = new StringBuilder();
        info.append(goodsName);
        
        if (spec != null && !spec.trim().isEmpty()) {
            info.append(" ").append(spec);
        }
        
        if (unit != null && !unit.trim().isEmpty()) {
            info.append(" (").append(unit).append(")");
        }
        
        return info.toString();
    }

    /**
     * 获取商品价格显示
     * 
     * @return 格式化的价格字符串
     */
    public String getPriceDisplay() {
        BigDecimal price = getActualPrice();
        if (price == null || price.compareTo(BigDecimal.ZERO) == 0) {
            return "价格待定";
        }
        return "¥" + price.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 获取金额显示
     * 
     * @return 格式化的金额字符串
     */
    public String getAmountDisplay() {
        if (amount == null) {
            return "¥0.00";
        }
        return "¥" + amount.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 验证销售明细数据完整性
     * 
     * @return 是否完整
     */
    public boolean isDataComplete() {
        return transactionId != null &&
               transactionNo != null && !transactionNo.trim().isEmpty() &&
               lineNo != null && lineNo > 0 &&
               goodsCode != null && !goodsCode.trim().isEmpty() &&
               goodsName != null && !goodsName.trim().isEmpty() &&
               unitPrice != null && unitPrice.compareTo(BigDecimal.ZERO) > 0 &&
               quantity != null && quantity.compareTo(BigDecimal.ZERO) > 0 &&
               amount != null && amount.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 获取销售明细摘要信息
     * 
     * @return 销售明细摘要
     */
    public String getSummary() {
        StringBuilder summary = new StringBuilder();
        summary.append("行号: ").append(lineNo);
        summary.append(", 商品: ").append(goodsName);
        summary.append(", 数量: ").append(quantity);
        summary.append(", 单价: ¥").append(getActualPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
        summary.append(", 金额: ¥").append(getAmountDisplay());
        
        if (isGift()) {
            summary.append(" (赠品)");
        }
        
        return summary.toString();
    }

    // ==================== 备用扩展字段 ====================
    
    /**
     * 备用字段1
     */
    private String reserved1;

    /**
     * 备用字段2
     */
    private String reserved2;

    /**
     * 备用字段3
     */
    private String reserved3;

    /**
     * 备用字段4
     */
    private String reserved4;

    /**
     * 备用字段5
     */
    private String reserved5;
}
